package com.sh.data.engine.domain.dataasset.job;

import com.sh.data.engine.domain.dataasset.service.TblPropService;
import com.sh.data.engine.domain.shims.db.BaseDbManager;
import com.sh.data.engine.domain.shims.sql.builder.DDLBuilder;
import com.sh.data.engine.domain.workspace.index.service.ProjectService;
import com.sh.data.engine.job.core.context.XxlJobHelper;
import com.sh.data.engine.job.core.handler.annotation.XxlJob;
import com.sh.data.engine.repository.dao.dataasset.entity.TblPropEntity;
import com.sh.data.engine.repository.dao.workspace.index.entity.ProjectEntity;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.sql.SQLException;
import java.util.Date;
import java.util.List;

/**
 * @Author: zigui.zdf @Date: 2022/5/24 10:57:44 @Description: 根据生命周期删除表
 */
@Component
@Slf4j
public class DropTblByLifecycleTask {

    @Autowired
    private TblPropService tblPropService;

    @Autowired
    private ProjectService projectService;

    @XxlJob("DropTblByLifecycleTask")
    public void run() {
        final List<ProjectEntity> projectEntities = projectService.findAll();

        if (CollectionUtils.isEmpty(projectEntities)) {
            XxlJobHelper.log("当前工作空间数量为0，本次同步结束...");
            return;
        }

        XxlJobHelper.log("当前工作空间数量为：{}", projectEntities.size());

        for (ProjectEntity projectEntity : projectEntities) {
            XxlJobHelper.log("正在处理：[{}]空间内的表", projectEntity.getName());

            long s = System.currentTimeMillis();

            try {
                run1(projectEntity.getId());
                XxlJobHelper.log(
                    "[{}]空间内的表处理结束，耗时:[{}]ms", projectEntity.getName(), System.currentTimeMillis() - s);
            } catch (Exception e) {
                log.error(e.getMessage(), e);
                XxlJobHelper.log(
                    "[{}]空间内的表处理异常，耗时:[{}]ms，原因：{}",
                    projectEntity.getName(),
                    System.currentTimeMillis() - s,
                    ExceptionUtils.getStackTrace(e));
            }
        }
    }

    private void run1(Long projectId) throws SQLException {
        final List<TblPropEntity> tblPropEntityList = tblPropService.getTblPropByProjectId(projectId);

        if (CollectionUtils.isEmpty(tblPropEntityList)) {
            XxlJobHelper.log("该工作空间内表数量为0，结束...");
            return;
        }

        final BaseDbManager dbManager = projectService.getDbManager(projectId);

        try (final DDLBuilder ddlBuilder = dbManager.getDDLBuilder()) {
            for (TblPropEntity tblPropEntity : tblPropEntityList) {
                run2(projectId, tblPropEntity, ddlBuilder);
            }
        }
    }

    private void run2(Long projectId, TblPropEntity tblPropEntity, DDLBuilder ddlBuilder)
        throws SQLException {
        final Date createTime = tblPropEntity.getCreateTime();
        final int lifecycle = tblPropEntity.getLifecycle();

        if (lifecycle <= 0) {
            return;
        }

        // 判断是否已过期
        if (DateUtils.addDays(createTime, lifecycle).before(new Date())) {
            XxlJobHelper.log(
                "info: table {}, schema {}, createTime is {}, lifecycle is {} days. this table is expired, will be dropped right now.",
                tblPropEntity.getTableName(),
                tblPropEntity.getSchema(),
                DateFormatUtils.format(createTime, "yyyy-MM-dd HH:mm:ss"),
                lifecycle);

            ddlBuilder.dropTable(tblPropEntity.getSchema(), tblPropEntity.getTableName()).execute();

            tblPropService.deleteTbl(projectId, tblPropEntity.getTblId());
        }
    }
}
